import 'package:dio/dio.dart';
import 'package:flutter_layout/config/env.dart';
import 'package:flutter_layout/utils/secure_storage.dart';

class Request {
  static Request? _instance;
  static Dio? _dio;

  factory Request() {
    _instance ??= Request._();
    return _instance!;
  }

  Request._() {
    _init();
  }

  void _init() {
    _dio = Dio(BaseOptions(
      baseUrl: envConfig.baseUrl,
      connectTimeout: Duration(minutes: 1),
      receiveTimeout: Duration(minutes: 1),
    ));

    _dio!.interceptors.add(
      InterceptorsWrapper(
        onRequest:
            (RequestOptions options, RequestInterceptorHandler handler) async {
          // 如果你想完成请求并返回一些自定义数据，你可以使用 `handler.resolve(response)`。
          // 如果你想终止请求并触发一个错误，你可以使用 `handler.reject(error)`。
          options.headers['Authorization'] =
              '${await Securestorage.get('token')}';
          return handler.next(options);
        },
        onResponse: (Response response, ResponseInterceptorHandler handler) {
          // 如果你想终止请求并触发一个错误，你可以使用 `handler.reject(error)`。
          return handler.next(response);
        },
        onError: (DioException error, ErrorInterceptorHandler handler) {
          // 如果你想完成请求并返回一些自定义数据，你可以使用 `handler.resolve(response)`。
          return handler.next(error);
        },
      ),
    );
  }

// 请求
  Future<Response<T>> request<T>({
    required String url,
    Object? data,
    Map<String, dynamic>? queryParameters,
    CancelToken? cancelToken,
    Map<String, dynamic>? options,
  }) async {
    // 配置options
    Options? dioOptions = Options(method: 'get');
    if (options != null) {
      dioOptions = dioOptions.copyWith(
          method: options['method'] ?? 'get',
          headers: options['headers'] ?? {});
    }
    return await _dio!.request(
      url,
      data: data,
      queryParameters: queryParameters,
      cancelToken: cancelToken,
      options: dioOptions,
    );
  }

  // 上传文件
  Future<Response<T>> uploadFile<T>(
      {String url = '/file-app/file/upload',
      CancelToken? cancelToken,
      required List<FileItem> data}) async {
    if (data.isEmpty) return Future.error('请选择文件');
    late FormData formData;
    if (data.length == 1) {
      // 单文件上传
      formData = FormData.fromMap({
        "file": await MultipartFile.fromFile(data[0].filepath,
            filename: data[0].filename),
      });
    } else {
      // 多文件上传
      final files = await Future.wait(data.map((e) async =>
          await MultipartFile.fromFile(e.filepath, filename: e.filename)));
      formData = FormData.fromMap({
        "files": files,
      });
    }
    return request(
        url: url,
        data: formData,
        cancelToken: cancelToken,
        options: {"method": "post", "content-type": "multipart/form-data"});
  }

  // 下载文件
  downloadFile(
      {required String urlPath,
      required String savePath,
      CancelToken? cancelToken,
      ProgressCallback? onReceiveProgress}) async {
    return _dio!.download(
      urlPath,
      savePath,
      cancelToken: cancelToken,
      onReceiveProgress: onReceiveProgress,
    );
  }
}

class FileItem {
  final String filepath;
  final String filename;

  FileItem({required this.filepath, required this.filename});
}
